home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / cvs-1_3.lha / cvs-1.3 / contrib / dirfns < prev    next >
Text File  |  1992-03-16  |  11KB  |  482 lines

  1. echo 'directory.3':
  2. sed 's/^X//' >'directory.3' <<'!'
  3. X.TH DIRECTORY 3 imported
  4. X.DA 9 Oct 1985
  5. X.SH NAME
  6. Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
  7. X.SH SYNOPSIS
  8. X.B #include <sys/types.h>
  9. X.br
  10. X.B #include <ndir.h>
  11. X.PP
  12. X.SM
  13. X.B DIR
  14. X.B *opendir(filename)
  15. X.br
  16. X.B char *filename;
  17. X.PP
  18. X.SM
  19. X.B struct direct
  20. X.B *readdir(dirp)
  21. X.br
  22. X.B DIR *dirp;
  23. X.PP
  24. X.SM
  25. X.B long
  26. X.B telldir(dirp)
  27. X.br
  28. X.B DIR *dirp;
  29. X.PP
  30. X.SM
  31. X.B seekdir(dirp, loc)
  32. X.br
  33. X.B DIR *dirp;
  34. X.br
  35. X.B long loc;
  36. X.PP
  37. X.SM
  38. X.B rewinddir(dirp)
  39. X.br
  40. X.B DIR *dirp;
  41. X.PP
  42. X.SM
  43. X.B closedir(dirp)
  44. X.br
  45. X.B DIR *dirp;
  46. X.SH DESCRIPTION
  47. XThis library provides high-level primitives for directory scanning,
  48. Xsimilar to those available for 4.2BSD's (very different) directory system.
  49. X.\"The purpose of this library is to simulate
  50. X.\"the new flexible length directory names of 4.2bsd UNIX
  51. X.\"on top of the old directory structure of v7.
  52. XIt incidentally provides easy portability to and from 4.2BSD (insofar
  53. Xas such portability is not compromised by other 4.2/VAX dependencies).
  54. X.\"It allows programs to be converted immediately
  55. X.\"to the new directory access interface,
  56. X.\"so that they need only be relinked
  57. X.\"when moved to 4.2bsd.
  58. X.\"It is obtained with the loader option
  59. X.\".BR \-lndir .
  60. X.PP
  61. X.I Opendir
  62. Xopens the directory named by
  63. X.I filename
  64. Xand associates a
  65. X.I directory stream
  66. Xwith it.
  67. X.I Opendir
  68. Xreturns a pointer to be used to identify the
  69. X.I directory stream
  70. Xin subsequent operations.
  71. XThe pointer
  72. X.SM
  73. X.B NULL
  74. Xis returned if
  75. X.I filename
  76. Xcannot be accessed or is not a directory.
  77. X.PP
  78. X.I Readdir
  79. Xreturns a pointer to the next directory entry.
  80. XIt returns
  81. X.B NULL
  82. Xupon reaching the end of the directory or detecting
  83. Xan invalid
  84. X.I seekdir
  85. Xoperation.
  86. X.PP
  87. X.I Telldir
  88. Xreturns the current location associated with the named
  89. X.I directory stream.
  90. X.PP
  91. X.I Seekdir
  92. Xsets the position of the next
  93. X.I readdir
  94. Xoperation on the
  95. X.I directory stream.
  96. XThe new position reverts to the one associated with the
  97. X.I directory stream
  98. Xwhen the
  99. X.I telldir
  100. Xoperation was performed.
  101. XValues returned by
  102. X.I telldir
  103. Xare good only for the lifetime of the DIR pointer from 
  104. Xwhich they are derived.
  105. XIf the directory is closed and then reopened, 
  106. Xthe 
  107. X.I telldir
  108. Xvalue may be invalidated
  109. Xdue to undetected directory compaction in 4.2BSD.
  110. XIt is safe to use a previous
  111. X.I telldir
  112. Xvalue immediately after a call to
  113. X.I opendir
  114. Xand before any calls to
  115. X.I readdir.
  116. X.PP
  117. X.I Rewinddir
  118. Xresets the position of the named
  119. X.I directory stream
  120. Xto the beginning of the directory.
  121. X.PP
  122. X.I Closedir
  123. Xcauses the named
  124. X.I directory stream
  125. Xto be closed,
  126. Xand the structure associated with the DIR pointer to be freed.
  127. X.PP
  128. XA
  129. X.I direct
  130. Xstructure is as follows:
  131. X.PP
  132. X.RS
  133. X.nf
  134. Xstruct    direct {
  135. X    /* unsigned */ long    d_ino;    /* inode number of entry */
  136. X    unsigned short    d_reclen;    /* length of this record */
  137. X    unsigned short    d_namlen;    /* length of string in d_name */
  138. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  139. X};
  140. X.fi
  141. X.RE
  142. X.PP
  143. XThe
  144. X.I d_reclen
  145. Xfield is meaningless in non-4.2BSD systems and should be ignored.
  146. XThe use of a
  147. X.I long
  148. Xfor
  149. X.I d_ino
  150. Xis also a 4.2BSDism;
  151. X.I ino_t
  152. X(see
  153. X.IR types (5))
  154. Xshould be used elsewhere.
  155. XThe macro
  156. X.I DIRSIZ(dp)
  157. Xgives the minimum memory size needed to hold the
  158. X.I direct
  159. Xvalue pointed to by
  160. X.IR dp ,
  161. Xwith the minimum necessary allocation for
  162. X.IR d_name .
  163. X.PP
  164. XThe preferred way to search the current directory for entry ``name'' is:
  165. X.PP
  166. X.RS
  167. X.nf
  168. X    len = strlen(name);
  169. X    dirp = opendir(".");
  170. X    if (dirp == NULL) {
  171. X        fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
  172. X        return NOT_FOUND;
  173. X    }
  174. X    while ((dp = readdir(dirp)) != NULL)
  175. X        if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
  176. X            closedir(dirp);
  177. X            return FOUND;
  178. X        }
  179. X    closedir(dirp);
  180. X    return NOT_FOUND;
  181. X.RE
  182. X.\".SH LINKING
  183. X.\"This library is accessed by specifying ``-lndir'' as the
  184. X.\"last argument to the compile line, e.g.:
  185. X.\".PP
  186. X.\"    cc -I/usr/include/ndir -o prog prog.c -lndir
  187. X.SH "SEE ALSO"
  188. Xopen(2),
  189. Xclose(2),
  190. Xread(2),
  191. Xlseek(2)
  192. X.SH HISTORY
  193. XWritten by
  194. XKirk McKusick at Berkeley (ucbvax!mckusick).
  195. XMiscellaneous bug fixes from elsewhere.
  196. XThe size of the data structure has been decreased to avoid excessive
  197. Xspace waste under V7 (where filenames are 14 characters at most).
  198. XFor obscure historical reasons, the include file is also available
  199. Xas
  200. X.IR <ndir/sys/dir.h> .
  201. XThe Berkeley version lived in a separate library (\fI\-lndir\fR),
  202. Xwhereas ours is
  203. Xpart of the C library, although the separate library is retained to
  204. Xmaximize compatibility.
  205. X.PP
  206. XThis manual page has been substantially rewritten to be informative in
  207. Xthe absence of a 4.2BSD manual.
  208. X.SH BUGS
  209. XThe
  210. X.I DIRSIZ
  211. Xmacro actually wastes a bit of space due to some padding requirements
  212. Xthat are an artifact of 4.2BSD.
  213. X.PP
  214. XThe returned value of
  215. X.I readdir
  216. Xpoints to a static area that will be overwritten by subsequent calls.
  217. X.PP
  218. XThere are some unfortunate name conflicts with the \fIreal\fR V7
  219. Xdirectory structure definitions.
  220. !
  221. echo 'dir.h':
  222. sed 's/^X//' >'dir.h' <<'!'
  223. X/*    dir.h    4.4    82/07/25    */
  224. X
  225. X/*
  226. X * A directory consists of some number of blocks of DIRBLKSIZ
  227. X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
  228. X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
  229. X *
  230. X * Each DIRBLKSIZ byte block contains some number of directory entry
  231. X * structures, which are of variable length.  Each directory entry has
  232. X * a struct direct at the front of it, containing its inode number,
  233. X * the length of the entry, and the length of the name contained in
  234. X * the entry.  These are followed by the name padded to a 4 byte boundary
  235. X * with null bytes.  All names are guaranteed null terminated.
  236. X * The maximum length of a name in a directory is MAXNAMLEN.
  237. X *
  238. X * The macro DIRSIZ(dp) gives the amount of space required to represent
  239. X * a directory entry.  Free space in a directory is represented by
  240. X * entries which have dp->d_reclen >= DIRSIZ(dp).  All DIRBLKSIZ bytes
  241. X * in a directory block are claimed by the directory entries.  This
  242. X * usually results in the last entry in a directory having a large
  243. X * dp->d_reclen.  When entries are deleted from a directory, the
  244. X * space is returned to the previous entry in the same directory
  245. X * block by increasing its dp->d_reclen.  If the first entry of
  246. X * a directory block is free, then its dp->d_ino is set to 0.
  247. X * Entries other than the first in a directory do not normally have
  248. X * dp->d_ino set to 0.
  249. X */
  250. X#define DIRBLKSIZ    512
  251. X#ifdef VMUNIX
  252. X#define    MAXNAMLEN    255
  253. X#else
  254. X#define    MAXNAMLEN    14
  255. X#endif
  256. X
  257. Xstruct    direct {
  258. X    /* unsigned */ long    d_ino;    /* inode number of entry */
  259. X    unsigned short    d_reclen;    /* length of this record */
  260. X    unsigned short    d_namlen;    /* length of string in d_name */
  261. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  262. X};
  263. X
  264. X/*
  265. X * The DIRSIZ macro gives the minimum record length which will hold
  266. X * the directory entry.  This requires the amount of space in struct direct
  267. X * without the d_name field, plus enough space for the name with a terminating
  268. X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
  269. X */
  270. X#undef DIRSIZ
  271. X#define DIRSIZ(dp) \
  272. X    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
  273. X
  274. X#ifndef KERNEL
  275. X/*
  276. X * Definitions for library routines operating on directories.
  277. X */
  278. Xtypedef struct _dirdesc {
  279. X    int    dd_fd;
  280. X    long    dd_loc;
  281. X    long    dd_size;
  282. X    char    dd_buf[DIRBLKSIZ];
  283. X} DIR;
  284. X#ifndef NULL
  285. X#define NULL 0
  286. X#endif
  287. Xextern    DIR *opendir();
  288. Xextern    struct direct *readdir();
  289. Xextern    long telldir();
  290. X#ifdef void
  291. Xextern    void seekdir();
  292. Xextern    void closedir();
  293. X#endif
  294. X#define rewinddir(dirp)    seekdir((dirp), (long)0)
  295. X#endif KERNEL
  296. !
  297. echo 'makefile':
  298. sed 's/^X//' >'makefile' <<'!'
  299. XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
  300. XCFLAGS=-O -I. -Dvoid=int
  301. XDEST=..
  302. X
  303. Xall:    $(DIR)
  304. X
  305. Xmv:    $(DIR)
  306. X    mv $(DIR) $(DEST)
  307. X
  308. Xcpif:    dir.h
  309. X    cp dir.h /usr/include/ndir.h
  310. X
  311. Xclean:
  312. X    rm -f *.o
  313. !
  314. echo 'closedir.c':
  315. sed 's/^X//' >'closedir.c' <<'!'
  316. Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
  317. X
  318. X#include <sys/types.h>
  319. X#include <dir.h>
  320. X
  321. X/*
  322. X * close a directory.
  323. X */
  324. Xvoid
  325. Xclosedir(dirp)
  326. X    register DIR *dirp;
  327. X{
  328. X    close(dirp->dd_fd);
  329. X    dirp->dd_fd = -1;
  330. X    dirp->dd_loc = 0;
  331. X    free((char *)dirp);
  332. X}
  333. !
  334. echo 'opendir.c':
  335. sed 's/^X//' >'opendir.c' <<'!'
  336. X/* Copyright (c) 1982 Regents of the University of California */
  337. X
  338. Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
  339. X
  340. X#include <sys/types.h>
  341. X#include <sys/stat.h>
  342. X#include <dir.h>
  343. X
  344. X/*
  345. X * open a directory.
  346. X */
  347. XDIR *
  348. Xopendir(name)
  349. X    char *name;
  350. X{
  351. X    register DIR *dirp;
  352. X    register int fd;
  353. X    struct stat statbuf;
  354. X    char *malloc();
  355. X
  356. X    if ((fd = open(name, 0)) == -1)
  357. X        return NULL;
  358. X    if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
  359. X        close(fd);
  360. X        return NULL;
  361. X    }
  362. X    if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  363. X        close (fd);
  364. X        return NULL;
  365. X    }
  366. X    dirp->dd_fd = fd;
  367. X    dirp->dd_loc = 0;
  368. X    dirp->dd_size = 0;    /* so that telldir will work before readdir */
  369. X    return dirp;
  370. X}
  371. !
  372. echo 'readdir.c':
  373. sed 's/^X//' >'readdir.c' <<'!'
  374. X/* Copyright (c) 1982 Regents of the University of California */
  375. X
  376. Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
  377. X
  378. X#include <sys/types.h>
  379. X#include <dir.h>
  380. X
  381. X/*
  382. X * read an old stlye directory entry and present it as a new one
  383. X */
  384. X#define    ODIRSIZ    14
  385. X
  386. Xstruct    olddirect {
  387. X    ino_t    od_ino;
  388. X    char    od_name[ODIRSIZ];
  389. X};
  390. X
  391. X/*
  392. X * get next entry in a directory.
  393. X */
  394. Xstruct direct *
  395. Xreaddir(dirp)
  396. X    register DIR *dirp;
  397. X{
  398. X    register struct olddirect *dp;
  399. X    static struct direct dir;
  400. X
  401. X    for (;;) {
  402. X        if (dirp->dd_loc == 0) {
  403. X            dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  404. X                DIRBLKSIZ);
  405. X            if (dirp->dd_size <= 0) {
  406. X                dirp->dd_size = 0;
  407. X                return NULL;
  408. X            }
  409. X        }
  410. X        if (dirp->dd_loc >= dirp->dd_size) {
  411. X            dirp->dd_loc = 0;
  412. X            continue;
  413. X        }
  414. X        dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
  415. X        dirp->dd_loc += sizeof(struct olddirect);
  416. X        if (dp->od_ino == 0)
  417. X            continue;
  418. X        dir.d_ino = dp->od_ino;
  419. X        strncpy(dir.d_name, dp->od_name, ODIRSIZ);
  420. X        dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
  421. X        dir.d_namlen = strlen(dir.d_name);
  422. X        dir.d_reclen = DIRBLKSIZ;
  423. X        return (&dir);
  424. X    }
  425. X}
  426. !
  427. echo 'seekdir.c':
  428. sed 's/^X//' >'seekdir.c' <<'!'
  429. Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
  430. X
  431. X#include <sys/param.h>
  432. X#include <dir.h>
  433. X
  434. X/*
  435. X * seek to an entry in a directory.
  436. X * Only values returned by "telldir" should be passed to seekdir.
  437. X */
  438. Xvoid
  439. Xseekdir(dirp, loc)
  440. X    register DIR *dirp;
  441. X    long loc;
  442. X{
  443. X    long curloc, base, offset;
  444. X    struct direct *dp;
  445. X    extern long lseek();
  446. X
  447. X    curloc = telldir(dirp);
  448. X    if (loc == curloc)
  449. X        return;
  450. X    base = loc & ~(DIRBLKSIZ - 1);
  451. X    offset = loc & (DIRBLKSIZ - 1);
  452. X    (void) lseek(dirp->dd_fd, base, 0);
  453. X    dirp->dd_size = 0;
  454. X    dirp->dd_loc = 0;
  455. X    while (dirp->dd_loc < offset) {
  456. X        dp = readdir(dirp);
  457. X        if (dp == NULL)
  458. X            return;
  459. X    }
  460. X}
  461. !
  462. echo 'telldir.c':
  463. sed 's/^X//' >'telldir.c' <<'!'
  464. Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
  465. X
  466. X#include <sys/types.h>
  467. X#include <dir.h>
  468. X
  469. X/*
  470. X * return a pointer into a directory
  471. X */
  472. Xlong
  473. Xtelldir(dirp)
  474. X    DIR *dirp;
  475. X{
  476. X    long lseek();
  477. X
  478. X    return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
  479. X}
  480. !
  481. echo done
  482.